//
//  server.c
//
//
//  Created by  AbbyCin on 10/28/14.
//  Copyright (c) 2014  AbbyCin. All rights reserved.
//

#include "Header.h"
#include "sock_act.h"
#include "utils.h"

void handler(int sig)
{
    while(waitpid(-1, NULL, WNOHANG) > 0)
        continue;
}

int main(int argc, const char * argv[])
{
  
    int sfd = 0;
    int acfd = 0;
    char *name = NULL;
    socklen_t client_len = sizeof(struct sockaddr_in);
    struct sockaddr_in client;
    int flags = LOG_NDELAY | LOG_PERROR | LOG_PID;
    int facility = LOG_ERR | LOG_INFO;
    char *buf = NULL;
    
    buf = malloc(MAX_SIZE);

    chroot("./"); /* run as root */
	chdir("./");
    openlog("abby's tiny httpd", flags, facility);
    
    bzero(&client,client_len);
    name = malloc(ADDR_LEN);

    sfd=Listen(argv[1],"30920", NULL, BACK_LOG);  /*   bind and listen; addr argv[1], port 30920 */
    if(sfd == -1)
    {
        syslog(LOG_ERR, "Listen errno: %s",strerror(errno));
        exit(EXIT_FAILURE);
    }
    
    signal(SIGCHLD, handler);
  
    for(;;)
    {
        if((acfd = accept(sfd, (SA *)&client, &client_len)) == -1)
        {
            if(errno != EINTR)
            {
                syslog(LOG_ERR,"accept error: %s",strerror(errno));
                break;
            }
        }
        
        memset(name, 0, ADDR_LEN);
        inet_ntop(AF_INET, &client.sin_addr, name, client_len);
        
        switch (fork()) {
            case -1:
                syslog(LOG_ERR,"fork error: %s",strerror(errno));
                exit(1);
            case 0:
                read(acfd, buf, MAX_SIZE);
                do_trans(acfd, buf);
                _exit(0);
            default:
                memset(buf, 0, MAX_SIZE);
                break;
        }
        close(acfd);
    }
    syslog(LOG_ERR, "Fatal error %s",strerror(errno));
    exit(errno);
}
